package com.steve.summary.saga.编制式.service;

import com.steve.summary.saga.common.model.Inventory;
import com.steve.summary.saga.common.model.Payment;
import com.steve.summary.saga.common.repository.InventoryRepository;
import com.steve.summary.saga.common.repository.OrderRepository;
import com.steve.summary.saga.common.repository.PaymentRepository;
import com.steve.summary.saga.common.model.Order;
import com.steve.summary.saga.common.status.PaymentStatus;
import com.steve.summary.saga.编制式.coordinator.Saga;
import com.steve.summary.saga.common.status.OrderStatus;
import com.steve.summary.saga.编制式.domain.SagaException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @Author: STEVE
 * @Description: 订单SAGA服务 - 使用编制式SAGA模式管理订单创建流程
 * @since: 2025-06-19
 */
@Service
public class OrderSagaService {

    @Autowired
    private OrderRepository orderRepository;
    @Autowired
    private InventoryRepository inventoryRepository;
    @Autowired
    private PaymentRepository paymentRepository;

    /**
     * 创建订单SAGA事务
     * 1. 创建订单
     * 2. 扣减库存
     * 3. 处理支付
     * 任何一个步骤失败都会触发补偿操作
     */
    public void createOrderSaga(Order order) {
        // 创建SAGA实例
        Saga saga = new Saga("CreateOrderSaga-" + order.getId());

        // 1. 步骤1：创建订单
        saga.addStep("CreateOrder",
                // 正向操作：创建订单
                () -> {
                    order.setStatus(OrderStatus.CREATED);
                    orderRepository.save(order);
                },
                // 补偿操作：取消订单
                () -> {
                    order.setStatus(OrderStatus.CANCELLED);
                    orderRepository.save(order);
                }
        );

        // 2. 步骤2：扣减库存
        saga.addStep("ReduceInventory",
                // 正向操作：扣减库存
                () -> {
                    Inventory inventory = inventoryRepository.findByProductId(order.getProductId()).orElseThrow(() -> new RuntimeException("Product not found"));
                    // 检查库存是否充足
                    if (inventory.getStock() < order.getAmount()) {
                        throw new RuntimeException("Insufficient stock");
                    }
                    // 扣减库存
                    inventory.setStock(inventory.getStock() - order.getAmount());
                    inventoryRepository.save(inventory);
                },
                // 补偿操作：恢复库存
                () -> {
                    Inventory inventory = inventoryRepository.findByProductId(order.getProductId()).orElseThrow(() -> new RuntimeException("Product not found"));
                    // 恢复库存
                    inventory.setStock(inventory.getStock() + order.getAmount());
                    inventoryRepository.save(inventory);
                }
        );

        // 3. 步骤3：处理支付
        saga.addStep("ProcessPayment",
                // 正向操作：处理支付并确认订单
                () -> {
                    // 创建支付记录
                    Payment payment = new Payment();
                    payment.setOrderId(order.getId());
                    payment.setAmount(order.getPrice());
                    payment.setStatus(PaymentStatus.COMPLETED);
                    paymentRepository.save(payment);
                    // 确认订单
                    order.setStatus(OrderStatus.CONFIRMED);
                    orderRepository.save(order);
                },
                // 补偿操作：退款
                () -> {
                    Payment payment = paymentRepository.findByOrderId(order.getId()).orElseThrow(() -> new RuntimeException("Payment not found"));
                    // 更新支付状态为已退款
                    payment.setStatus(PaymentStatus.REFUNDED);
                    paymentRepository.save(payment);
                }
        );

        try {
            saga.execute(); // 执行SAGA事务
        } catch (SagaException e) {
            System.err.println("Order creation failed: " + e.getMessage());
            throw e;
        }

    }

}
